Skip to content

feat: add ArrayContains decorator#192

Open
yuchem2 wants to merge 6 commits intodevelopfrom
CARGO-364
Open

feat: add ArrayContains decorator#192
yuchem2 wants to merge 6 commits intodevelopfrom
CARGO-364

Conversation

@yuchem2
Copy link
Member

@yuchem2 yuchem2 commented Mar 8, 2026

@ArrayContrains 데코레이터를 추가합니다.

복합 타입이나 객체 배열의 경우 깊은 비교로 인해 성능 저하를 막을 수 없기 때문에 주의사항을 문서에 추가하였습니다.

@auto-assign auto-assign bot requested review from dami0806, laggu and sezeme March 8, 2026 12:12
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 express-cargo 라이브러리에 새로운 @ArrayContains 유효성 검사 데코레이터를 도입하여 배열 유효성 검사 기능을 확장합니다. 이 추가는 개발자가 배열 필드가 특정 필수 요소를 포함하는지 쉽게 확인할 수 있도록 하여 데이터 유효성 검사의 유연성과 견고성을 향상시킵니다. 이 변경 사항은 라이브러리의 유효성 검사 기능을 풍부하게 하고 다양한 데이터 구조에 대한 보다 정교한 유효성 검사 규칙을 가능하게 합니다.

Highlights

  • 새로운 @ArrayContains 데코레이터 추가: express-cargo 라이브러리에 배열이 지정된 모든 값을 포함하는지 검증하는 @ArrayContains 데코레이터가 추가되었습니다.
  • 다국어 문서 업데이트: 새로운 @ArrayContains 데코레이터에 대한 설명이 한국어, 영어, 독일어, 프랑스어, 러시아어 README 및 문서 파일에 추가되었습니다.
  • 사용 예시 및 테스트 추가: apps/example 프로젝트에 @ArrayContains 데코레이터의 사용 예시가 추가되었으며, 새로운 유효성 검사기에 대한 단위 테스트도 작성되었습니다.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • README.ko.md
    • @ArrayContains 데코레이터에 대한 한국어 설명이 추가되었습니다.
  • README.md
    • @ArrayContains 데코레이터에 대한 영어 설명이 추가되었습니다.
  • apps/docs/docs/decorators/validators.md
    • @ArrayContains 데코레이터에 대한 문서가 추가되었습니다.
  • apps/docs/i18n/de/docusaurus-plugin-content-docs/current/decorators/validators.md
    • @ArrayContains 데코레이터에 대한 독일어 문서가 추가되었습니다.
  • apps/docs/i18n/fr/docusaurus-plugin-content-docs/current/decorators/validators.md
    • @ArrayContains 데코레이터에 대한 프랑스어 문서가 추가되었습니다.
  • apps/docs/i18n/ko/docusaurus-plugin-content-docs/current/decorators/validators.md
    • @ArrayContains 데코레이터에 대한 한국어 문서가 추가되었습니다.
  • apps/docs/i18n/ru/docusaurus-plugin-content-docs/current/decorators/validators.md
    • @ArrayContains 데코레이터에 대한 러시아어 문서가 추가되었습니다.
  • apps/example/README.md
    • @ArrayContains 데코레이터의 사용 예시가 추가되었습니다.
  • apps/example/src/routers/validator.ts
    • ArrayContains 데코레이터가 가져와지고 이를 사용하는 예시 라우트와 클래스가 추가되었습니다.
  • packages/express-cargo/src/validator.ts
    • ArrayContains 데코레이터의 구현이 추가되었습니다.
  • packages/express-cargo/tests/validator/arrayContains.test.ts
    • ArrayContains 유효성 검사기에 대한 새로운 단위 테스트 파일이 추가되었습니다.
Activity
  • 아직 이 PR에 대한 사람의 활동은 없습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

새로운 @ArrayContains 데코레이터 추가 및 관련 문서와 예제를 업데이트한 풀 리퀘스트입니다. 전반적으로 구현이 잘 되었지만, ArrayContains 데코레이터의 유효성 검사 로직에서 성능을 개선할 수 있는 부분이 있습니다. 큰 배열을 처리할 때의 효율성을 높이기 위해 Set을 사용하는 것을 제안합니다. 자세한 내용은 코드 리뷰 코멘트를 참고해주세요.

@yuchem2
Copy link
Member Author

yuchem2 commented Mar 8, 2026

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This PR introduces a new @ArrayContains decorator, including its implementation, documentation, and examples. However, a critical vulnerability has been identified in its core validation logic. The implementation is inverted, causing it to fail for all arrays and potentially crash the server with non-iterable inputs, posing a minor stability risk (DoS via 500 errors). This bug renders the decorator unusable and requires immediate correction.

@yuchem2
Copy link
Member Author

yuchem2 commented Mar 13, 2026

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

새로운 @ArrayContains 데코레이터 추가와 관련 문서 및 예제 작성을 포함한 기여에 감사드립니다. 전반적으로 좋은 구현이지만, 몇 가지 개선점을 제안합니다. isDeepEqual 유틸리티 함수에서 순환 참조를 처리하지 못해 무한 루프에 빠질 수 있는 심각한 문제가 발견되었습니다. 또한, 예제 코드의 @Type 데코레이터에서 null 값을 제대로 처리하지 못하는 잠재적 버그가 있으며, 스타일 가이드에 따라 일부 주석을 한국어로 변경할 것을 제안합니다. 자세한 내용은 각 파일의 주석을 참고해주세요.

Comment on lines +1 to +35
export function isDeepEqual(obj1: any, obj2: any): boolean {
if (obj1 === obj2) return true

const stack: [any, any][] = [[obj1, obj2]]
while (stack.length > 0) {
const [a, b] = stack.pop()!

if (a === b) continue
if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) {
return false
}

// Handle Date objects specifically
if (a instanceof Date && b instanceof Date) {
if (a.getTime() !== b.getTime()) return false
continue
}

// Check if both are arrays or neither (for accuracy and performance)
const isArrayA = Array.isArray(a)
const isArrayB = Array.isArray(b)
if (isArrayA !== isArrayB) return false

const keysA = Object.keys(a)
const keysB = Object.keys(b)
if (keysA.length !== keysB.length) return false

for (const key of keysA) {
if (!Object.prototype.hasOwnProperty.call(b, key)) return false
stack.push([a[key], b[key]])
}
}

return true
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

isDeepEqual 함수는 순환 참조(circular reference)가 있는 객체를 처리할 때 무한 루프에 빠질 수 있는 취약점이 있습니다. 이는 서비스 거부(DoS) 공격으로 이어질 수 있습니다. 예를 들어, const a = {}; a.a = a;와 같은 객체가 입력으로 들어오면 스택에 동일한 비교 쌍이 계속 추가되어 무한 루프가 발생합니다.

이 문제를 해결하기 위해 이미 비교한 객체 쌍을 추적하는 메커니즘을 추가해야 합니다. MapSet을 사용하여 방문한 객체 쌍을 기록하는 방식으로 수정하는 것을 제안합니다.

export function isDeepEqual(obj1: any, obj2: any): boolean {
    if (obj1 === obj2) return true

    // 순환 참조를 처리하기 위해 방문한 객체 쌍을 추적합니다.
    const visited = new Map<object, Set<object>>()
    const stack: [any, any][] = [[obj1, obj2]]

    while (stack.length > 0) {
        const [a, b] = stack.pop()!

        if (a === b) continue
        if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) {
            return false
        }

        // 이미 비교한 쌍이면 건너뜁니다.
        if (visited.has(a) && visited.get(a)!.has(b)) {
            continue
        }
        if (!visited.has(a)) {
            visited.set(a, new Set())
        }
        visited.get(a)!.add(b)

        // Date 객체를 특별히 처리합니다.
        if (a instanceof Date && b instanceof Date) {
            if (a.getTime() !== b.getTime()) return false
            continue
        }

        // 두 값 모두 배열이거나 아니어야 합니다.
        const isArrayA = Array.isArray(a)
        const isArrayB = Array.isArray(b)
        if (isArrayA !== isArrayB) return false

        const keysA = Object.keys(a)
        const keysB = Object.keys(b)
        if (keysA.length !== keysB.length) return false

        for (const key of keysA) {
            if (!Object.prototype.hasOwnProperty.call(b, key)) return false
            stack.push([a[key], b[key]])
        }
    }

    return true
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HTTP 요청의 JSON 데이터는 직렬화된 문자열 형태로 전송되며, 표준 JSON 규격상 순환 참조를 포함할 수 없습니다. 또한, 우리 라이브러리 이전 단계인 express.json()에서 JSON.parse()를 통해 객체화되는데, 이 과정에서 순환 구조가 있다면 이미 파싱 에러가 발생합니다.

그러므로 발생할 수 없는 케이스를 위해 모든 객체 노드를 순회하며 순환 참조를 체크하는 로직을 추가하는 것은 라이브러리의 성능에 불필요한 비용을 발생시킨다고 생각하여 해당 리뷰는 반영하지 않도록 하겠습니다.

@yuchem2 yuchem2 requested a review from laggu March 13, 2026 14:21
* @param values - The values that must be present in the array.
* @param message - Optional custom error message.
*/
export function ArrayContains(values: any[], message?: cargoErrorMessage): TypedPropertyDecorator<any[]> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

equal 여부 판단을 위한 함수도 optional 로 개발자가 입력할수 있게 하면 어떨가요?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기본적으로 저희가 제공하는 함수를 사용하되, 추가적인 옵션을 받자는 말씀이신가요?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네네 맞아요

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 한번 반영해보도록 할게요!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants